import docutils.core
from docutils import writers

import docutils
from docutils import frontend, writers
from docutils import languages, Component
from docutils.transforms import universal
from docutils.transforms import math

__docformat__ = 'reStructuredText'

class MWriter(writers.Writer, Component):

    supported = ('xml',)
    """Formats this writer supports."""

    settings_spec = (
        '"Docutils XML" Writer Options',
        'Warning: the --newlines and --indents options may adversely affect '
        'whitespace; use them only for reading convenience.',
        (('Generate XML with newlines before and after tags.',
          ['--newlines'],
          {'action': 'store_true', 'validator': frontend.validate_boolean}),
         ('Generate XML with indents and newlines.',
          ['--indents'],
          {'action': 'store_true', 'validator': frontend.validate_boolean}),
         ('Omit the XML declaration.  Use with caution.',
          ['--no-xml-declaration'],
          {'dest': 'xml_declaration', 'default': 1, 'action': 'store_false',
           'validator': frontend.validate_boolean}),
         ('Omit the DOCTYPE declaration.',
          ['--no-doctype'],
          {'dest': 'doctype_declaration', 'default': 1,
           'action': 'store_false', 'validator': frontend.validate_boolean}),
          ('Convert LaTeX math in math_block and math to MathML',
              ['--latex-mathml'],
              {'dest': 'latex_mathml', 'default':False,
                  'action': 'store_true', 'validator': frontend.validate_boolean}),
            ('Convert ASCII math in math_block and math to MathML',
              ['--ascii-mathml'],
              {'dest': 'ascii_mathml', 'default':False,
                  'action': 'store_true', 'validator': frontend.validate_boolean}),
          
          ))

    settings_defaults = {'output_encoding_error_handler': 'xmlcharrefreplace'}

    config_section = 'docutils_xml writer'
    config_section_dependencies = ('writers',)

    output = None
    """Final translated form of `document`."""

    xml_declaration = '<?xml version="1.0" encoding="%s"?>\n'
    #xml_stylesheet = '<?xml-stylesheet type="text/xsl" href="%s"?>\n'
    doctype = (
        '<!DOCTYPE document PUBLIC'
        ' "+//IDN docutils.sourceforge.net//DTD Docutils Generic//EN//XML"'
        ' "http://docutils.sourceforge.net/docs/ref/docutils.dtd">\n')
    generator = '<!-- Generated by Docutils %s -->\n'

    def get_transforms(self):
        return Component.get_transforms(self) + [
            universal.Messages,
            universal.FilterMessages,
            universal.StripClassesAndElements,
            math.LaTeXmath2MathML,
            math.Asciimath2MathML,
            ]

    def translate(self):
        settings = self.document.settings
        indent = newline = ''
        if settings.newlines:
            newline = '\n'
        if settings.indents:
            newline = '\n'
            indent = '    '
        output_prefix = []
        if settings.xml_declaration:
            output_prefix.append(
                self.xml_declaration % settings.output_encoding)
        if settings.doctype_declaration:
            output_prefix.append(self.doctype)
        output_prefix.append(self.generator % docutils.__version__)
        docnode = self.document.asdom().childNodes[0]
        self.output = (''.join(output_prefix)
                       + docnode.toprettyxml(indent, newline))


class MPublisher(docutils.core.Publisher):
    pass



    def set_writer(self, writer_name):
        """Set `self.writer` by name."""
        writer_class = writers.get_writer_class(writer_name)
        # self.writer = writer_class()
        self.writer = MWriter()

"""
A minimal front end to the Docutils Publisher, producing Docutils XML.
"""

try:
    import locale
    locale.setlocale(locale.LC_ALL, '')
except:
    pass

# from docutils.core import publish_cmdline, default_description
from docutils.core import  default_description


description = ('Generates Docutils-native XML from standalone '
               'reStructuredText sources.  ' + default_description)
default_usage = '%prog [options] [<source> [<destination>]]'
default_description = ('Reads from <source> (default is stdin) and writes to '
                       '<destination> (default is stdout).  See '
                       '<http://docutils.sf.net/docs/user/config.html> for '
                       'the full reference.')


def publish_cmdline(reader=None, reader_name='standalone',
                    parser=None, parser_name='restructuredtext',
                    writer=None, writer_name='pseudoxml',
                    settings=None, settings_spec=None,
                    settings_overrides=None, config_section=None,
                    enable_exit_status=1, argv=None,
                    usage=default_usage, description=default_description):
    """
    Set up & run a `Publisher` for command-line-based file I/O (input and
    output file paths taken automatically from the command line).  Return the
    encoded string output also.

    Parameters: see `publish_programmatically` for the remainder.

    - `argv`: Command-line argument list to use instead of ``sys.argv[1:]``.
    - `usage`: Usage string, output if there's a problem parsing the command
      line.
    - `description`: Program description, output for the "--help" option
      (along with command-line option descriptions).
    """
    pub = MPublisher(reader, parser, writer, settings=settings)
    pub.set_components(reader_name, parser_name, writer_name)
    output = pub.publish(
        argv, usage, description, settings_spec, settings_overrides,
        config_section=config_section, enable_exit_status=enable_exit_status)
    return output

publish_cmdline(writer_name='xml', description=description)
